
"""utilities for working with packages

Most of this code was originally written by Christopher Arndt (http://paddyland.serveblog.net/) for EggBasket (http://pypi.python.org/pypi/EggBasket/).
It has been modified to work without a filesystem

"""

import logging
import zipfile
import tarfile
import email
from cStringIO import StringIO
from pypione.exc import PkgInfoNotFound, UnsupportedFormatError

log = logging.getLogger()

def has_extension(filename, extensions=[], case_sensitive=False):
    """Return True if filename has one of the given extensions, False otherwise.
    """
    if not case_sensitive:
        filename = filename.lower()
    for extension in extensions:
        if not case_sensitive:
            extension = extension.lower()
        if filename.endswith(extension):
            return True
    return False
    
def read_pkg_info_from_tar(filename, contents):
    """Read PKG-INFO file from (compressed/gzipped/bzipped) tar file."""
    buf = StringIO(contents)
    try:
        tar = tarfile.open(filename, 'r', buf)
    except tarfile.TarError:
        raise UnsupportedFormatError("Unsupported tar file")
    try:
        # get path of PKG-INFO file in archive
        pkg_info_filename = (i.name for i in tar
            if i.name.endswith('egg-info/PKG-INFO')).next()
        fo = tar.extractfile(pkg_info_filename)
    except (StopIteration, tarfile.TarError), exc:
        raise PkgInfoNotFound("Can't read PKG-INFO from '%s'." % filename)
    else:
        pkg_info_src = fo.read()
    fo.close()
    tar.close()

    return pkg_info_src

def read_pkg_info_from_egg(filename, contents):
    """Read PKG-INFO file from Python egg file or directory."""
    try:
        pkg = zipfile.ZipFile(StringIO(contents), 'r')
    except zipfile.error:
        raise IOError("Can't read egg/zip file '%s'." % filename)
    try:
        pkg_info_filename = (name for name in pkg.namelist()
            if name.endswith('/PKG-INFO')).next()
        pkg_info_src = pkg.read(pkg_info_filename)
    except (StopIteration, zipfile.error), exc:
        raise PkgInfoNotFound(
            "Can't read PKG-INFO from '%s'." % filename)
    pkg.close()

    return pkg_info_src

def unpack_pkg_info(metadata):
    """accepts PKG_INFO contents and returns dict"""
    msg = email.message_from_string(metadata) 
    metadata = {}
    for header in [l for l in msg._headers]:
        metadata[header[0]] = header[1]

    return metadata
